package core.proto.vis.controls;

import java.awt.Cursor;
import java.awt.event.MouseEvent;

import core.util.logging.SimpleLogger;
import core.util.logging.constants.Location;

import prefuse.Display;
import prefuse.controls.Control;
import prefuse.controls.ControlAdapter;
import prefuse.util.ui.UILib;
import prefuse.visual.VisualItem;

public class PanControl extends ControlAdapter
{
    private static final SimpleLogger LOGGER = SimpleLogger.getLogger();

    private boolean m_panOverItem;

    private int m_xDown, m_yDown;

    private int m_button;

    /**
     * Create a new PanControl.
     */
    public PanControl() {
        this( LEFT_MOUSE_BUTTON, false );
    }

    /**
     * Create a new PanControl.
     * 
     * @param panOverItem
     *            if true, the panning control will work even while the mouse is
     *            over a visual item.
     */
    public PanControl( boolean panOverItem ) {
        this( LEFT_MOUSE_BUTTON, panOverItem );
    }

    /**
     * Create a new PanControl.
     * 
     * @param mouseButton
     *            the mouse button that should initiate a pan. One of
     *            {@link Control#LEFT_MOUSE_BUTTON},
     *            {@link Control#MIDDLE_MOUSE_BUTTON}, or
     *            {@link Control#RIGHT_MOUSE_BUTTON}.
     */
    public PanControl( int mouseButton ) {
        this( mouseButton, false );
    }

    /**
     * Create a new PanControl
     * 
     * @param mouseButton
     *            the mouse button that should initiate a pan. One of
     *            {@link Control#LEFT_MOUSE_BUTTON},
     *            {@link Control#MIDDLE_MOUSE_BUTTON}, or
     *            {@link Control#RIGHT_MOUSE_BUTTON}.
     * @param panOverItem
     *            if true, the panning control will work even while the mouse is
     *            over a visual item.
     */
    public PanControl( int mouseButton, boolean panOverItem ) {
        m_button = mouseButton;
        m_panOverItem = panOverItem;
    }

    // ------------------------------------------------------------------------

    /**
     * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
     */
    public void mousePressed( MouseEvent e ) {
        if( UILib.isButtonPressed( e, m_button ) ) {
            e.getComponent().setCursor(
                    Cursor.getPredefinedCursor( Cursor.MOVE_CURSOR ) );
            m_xDown = e.getX();
            m_yDown = e.getY();
        }
    }

    /**
     * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
     */
    public void mouseDragged( MouseEvent e ) {
        if( UILib.isButtonPressed( e, m_button ) ) {
            Display display = (Display) e.getComponent();
            int x = e.getX(), y = e.getY();
            int dx = x - m_xDown, dy = y - m_yDown;
            display.pan( dx, dy );
            m_xDown = x;
            m_yDown = y;
            display.repaint();
        }
    }

    /**
     * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
     */
    public void mouseReleased( MouseEvent e ) {
        if( UILib.isButtonPressed( e, m_button ) ) {
            e.getComponent().setCursor( Cursor.getDefaultCursor() );
            m_xDown = -1;
            m_yDown = -1;
        }
        LOGGER.log( Location.VZ, "pan-action on visualization" );
    }

    /**
     * @see prefuse.controls.Control#itemPressed(prefuse.visual.VisualItem,
     *      java.awt.event.MouseEvent)
     */
    public void itemPressed( VisualItem item, MouseEvent e ) {
        if( m_panOverItem )
            mousePressed( e );
    }

    /**
     * @see prefuse.controls.Control#itemDragged(prefuse.visual.VisualItem,
     *      java.awt.event.MouseEvent)
     */
    public void itemDragged( VisualItem item, MouseEvent e ) {
        if( m_panOverItem )
            mouseDragged( e );
    }

    /**
     * @see prefuse.controls.Control#itemReleased(prefuse.visual.VisualItem,
     *      java.awt.event.MouseEvent)
     */
    public void itemReleased( VisualItem item, MouseEvent e ) {
        if( m_panOverItem )
            mouseReleased( e );
    }

} // end of class PanControl
